package com.CmJava.controller;


import com.CmJava.entity.MessageList;
import com.CmJava.entity.ResultEntity;
import com.CmJava.service.JwtService;
import com.CmJava.service.MessageService;
import com.alibaba.dubbo.config.annotation.Reference;
import org.apache.commons.codec.binary.Base64;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@RestController
public class MessageController {

    private static HashMap<String, byte[]> fileMap = new HashMap<>();

    private static final Timer timer = new Timer("clearFileTimer");

    private static long currentTime = 0;

    @Reference
    private MessageService messageService;

    @Reference
    private JwtService jwtService;

    static {
        //超过一天未下载则去除
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                try {
                    currentTime = new Date(System.currentTimeMillis()).getTime();
                    long saveTime = 0;
                    String time0 = "";
                    if (fileMap.size() > 0) {
                        for (String key : fileMap.keySet()) {
                            time0 = key.split("@@---@@")[1];
                            saveTime = Long.parseLong(time0);
                            if ((currentTime - saveTime) > 2 * 1000 * 60 * 24) {
                                fileMap.remove(key);
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, 1000, 2 * 1000 * 60 * 24);
    }

    // 保存聊天记录
    @PostMapping("saveMessage")
    public ResultEntity saveMessage(@RequestParam("userName") String userName,
                                    @RequestParam("friendName") String friendName,
                                    @RequestParam("message") String message,
                                    @RequestParam("time") String time,
                                    @RequestParam("num") String num,
                                    @RequestParam("token") String token) {
        boolean flag = false;

        flag = jwtService.compareJwt(userName, token);
        if (!flag) {
            return ResultEntity.failureWithoutMessage();
        }

        flag = messageService.saveMessage(userName, friendName, message, time, Integer.parseInt(num));
        if (flag) {
            return ResultEntity.successWithoutMessage();
        } else {
            return ResultEntity.failureWithoutMessage();
        }
    }

    // 获取聊天记录
    @PostMapping("getMessage")
    public ResultEntity getMessage(@RequestParam("userName") String userName,
                                   @RequestParam("friendList") String friendList) {


        List<MessageList> messageList = messageService.getMessage(userName, friendList);
        for (MessageList list : messageList) {
            if (list != null) {
                return ResultEntity.successWithMessage(messageList);
            }
        }
        return ResultEntity.successWithMessage("目前无未读消息");
    }

    // 发送文件
    @PostMapping("sendFile")
    public ResultEntity sendFile(@RequestParam("name") String name,
                                 @RequestParam("file") MultipartFile multipartFile) {
        byte[] bytes = null;
        try {
            bytes = multipartFile.getBytes();
            if (bytes != null) {
                currentTime = new Date(System.currentTimeMillis()).getTime();
                fileMap.put(name + "@@---@@" + currentTime, bytes);
            } else {
                throw new RuntimeException("获取文件二进制流失败...");
            }
        } catch (IOException e) {
            return ResultEntity.failureWithoutMessage();
        }

        return ResultEntity.successWithoutMessage();
    }

    //下载文件
    @GetMapping("getFile")
    public ResultEntity getFile(@RequestParam("fileMessage") String fileMessage, HttpServletResponse response) {
        byte[] bytes = null;
        ServletOutputStream outputStream = null;
        String fileName = "";

        try {
            for (String key : fileMap.keySet()) {
                if (key.contains(fileMessage.split("@@")[0]) &&
                        key.contains(fileMessage.split("@@")[1])) {
                    bytes = fileMap.get(key);
                    fileName = key.split("：")[2].substring(3);
                    break;
                }
            }
            if (bytes == null) {
                response.sendRedirect("/privateChat.html");
                return null;
            }

            //URLEncoder编码中文文件名
            response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));

            outputStream = response.getOutputStream();
            outputStream.write(bytes);
            outputStream.flush();
        } catch (IOException e) {
            return ResultEntity.failureWithoutMessage();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return ResultEntity.successWithoutMessage();
    }

    // 获取文件是否存在
    @PostMapping("fileExist")
    public ResultEntity fileExist(@RequestParam("userToUser") String userToUser,
                                  @RequestParam("fileName") String fileName) {

        for (String key : fileMap.keySet()) {
            if (key.contains(userToUser) &&
                    key.contains(fileName)) {

                return ResultEntity.successWithoutMessage();
            }
        }
        return ResultEntity.failureWithoutMessage();
    }

}
